﻿using System;
using System.Data; 
using System.Drawing;
using System.Drawing.Printing;
using System.Collections.Generic;

namespace PlanningGIS.Statistics 
{
    /// <summary>
    /// 名    称：ReportClass
    /// 作    用：报表类
    /// 开发人员：张利勇
    /// 开发日期：2009-03-25
    /// 修改人员：
    /// 修改日期：
    /// 修改说明：
    /// </summary>
	public class ReportClass
	{
		#region Constructors
		public ReportClass()
		{
			MyDoc = ReportPrintDocument;
			MyDoc.PrintPage += new PrintPageEventHandler(PrintReport) ;
			InitializeFields();
		}
		#endregion

		#region Fields
        private int pagesPrinted = 0;
		private int ReportRowCount = 0;
		private decimal[] TotCol = new decimal[0];
		public PrintDocument MyDoc = new PrintDocument();
		private DataTable dt = new DataTable();
		private bool bIsLandscape;
		private bool bReportHasLogo;
		private bool bReportHasTitle;
		private bool bReportTitleFirstPageOnly; 
		private int iReportLogoHeight;
		private int iReportLogoWidth;
		private int iReportTitleHeight;
		private Font fntReportTitleFont;
		private Font fntReportHeaderFont;
		private Font fntReportBodyFont;
		private Brush brReportTitleFontColor;
		private Brush brReportHeaderBackgroundColor; 
		private Brush brReportHeaderFontColor; 
		private bool bReportHideGrid;
		private StringAlignment saReportHeaderCellAlignment;
		private StringAlignment saReportTitleAlignment; 
		private StringAlignment saReportNumericAlignment; 
		private bool bReportShowTotals;
		private int iTableWidth;
		private string sReportTitle;
		private Image imReportLogo;
		private int iHeaderRowHeight;
		private int iRowHeight;
        public List<String> AggrTexts = new List<string>();
		#endregion

		#region Properties

        public int PagesPrinted
        {
            get { return pagesPrinted; }
            set { pagesPrinted = value; }
        }

		/// <summary>
		/// Gets or Sets the PrintDocument for the report
		/// </summary>
		private PrintDocument _ReportPrintDocument = new PrintDocument();
		public PrintDocument ReportPrintDocument
		{
			get {return _ReportPrintDocument; }
			set {_ReportPrintDocument = value;}
		}

		/// <summary>
		/// Gets or Sets the page orientation of the report
		/// </summary>
		private bool _IsLandscape  = false;
		public bool IsLandscape
		{
			get { return _IsLandscape;  }
			set 
			{
				_IsLandscape = value;
				MyDoc.DefaultPageSettings.Landscape = value;
				bIsLandscape = value;
			}
		}

		/// <summary>
		/// Gets or Sets the source data for the report
		/// </summary>
		private DataTable _ReportSource;
		public  DataTable ReportSource  
		{
			get {   return _ReportSource;  }
			set {   
					_ReportSource = value; 
					dt = value;
				}
		}
    
		/// <summary>
		///Gets or Sets the table width of the report 
		/// </summary>
		private int _TableWidth = 0;
		public  int TableWidth
		{
			get {  return _TableWidth; }
			set {  
					_TableWidth = value;
					iTableWidth = _TableWidth;
				}
		}
    
		/// <summary>
		/// Gets or Sets the row height of the report
		/// </summary>
		private int _RowHeight  = 20;
		public  int RowHeight  
		{
			get {return _RowHeight;}
			set { 
					_RowHeight = value;  
					iRowHeight = _RowHeight;
				}
		}
    
  		/// <summary>
		/// Gets or Sets the header row height of the report
		/// </summary>
		private int _HeaderRowHeight = 30;
		public  int HeaderRowHeight
		{
			get { return _HeaderRowHeight; }
			set { 
					_HeaderRowHeight = value;
					iHeaderRowHeight = _HeaderRowHeight;
				}
		}

		/// <summary>
		/// Gets or Sets the title height of the report
		/// </summary>
		private int _TitleHeight = 40;
		public  int TitleHeight
		{
			get {return _TitleHeight;}
			set {
					_TitleHeight = value;
					iReportTitleHeight = _TitleHeight;
				}
		}

        private List<int> _ColWidths = new List<int>();
        public List<int> ColWidths
        {
            get { return _ColWidths; }
            set
            {
                _ColWidths = value;
            }
        }
    
		/// <summary>
		/// Gets or Sets the height of the logo
		/// </summary>
		private int _LogoHeight = 75;
		public  int LogoHeight
		{
			get {return _LogoHeight;}
			set {
					_LogoHeight = value;
					iReportLogoHeight = _LogoHeight; 
				}
		}
    
		/// <summary>
		/// Gets or Sets the width of the logo
		/// </summary>
		private int _LogoWidth  = 150;
		public  int LogoWidth
		{
			get {return _LogoWidth;}
			set { 
					_LogoWidth = value;
					iReportLogoWidth = _LogoWidth; 
				}
		}

		/// <summary>
		/// Gets or Sets the alignment of the title
		/// </summary>
		private StringAlignment _NumericAlignment = StringAlignment.Near ;
		public  StringAlignment NumericAlignment  
		{
			get {return _NumericAlignment;}
			set 
			{
				_NumericAlignment = value;
				saReportNumericAlignment = _NumericAlignment; 
			}
		}

		/// <summary>
		/// Gets or Sets the alignment of the title
		/// </summary>
		private StringAlignment _TitleAlignment = StringAlignment.Center;
		public  StringAlignment TitleAlignment  
		{
			get {return _TitleAlignment;}
			set {
					_TitleAlignment = value;
					saReportTitleAlignment = _TitleAlignment; 
				}
		}
		    
		/// <summary>
		/// Gets or Sets the header cell alignment 
		/// </summary>
		private StringAlignment _HeaderCellAlignment   = StringAlignment.Near ;
		public  StringAlignment HeaderCellAlignment
		{
			get {return _HeaderCellAlignment;}
			set {
					_HeaderCellAlignment = value;
					saReportHeaderCellAlignment = _HeaderCellAlignment; 
				}
		}

		/// <summary>
		/// Gets or Sets the title font color
		/// </summary>
		private Brush _TitleFontColor = Brushes.Black;
		public  Brush TitleFontColor  
		{
			get {return _TitleFontColor;}
			set {
					_TitleFontColor = value;
					brReportTitleFontColor = _TitleFontColor; 
				}
		}

		/// <summary>
		/// Gets or Sets the header font color
		/// </summary>
		private Brush _HeaderFontColor = Brushes.Black;
		public  Brush HeaderFontColor  
		{
			get {return _HeaderFontColor;}
			set {
					_HeaderFontColor = value;
					brReportHeaderFontColor = _HeaderFontColor; 
				}
		}
		    
		/// <summary>
		/// Gets or Sets the header background color
		/// </summary>
		private Brush _HeaderBackgroundColor = Brushes.White;
		public  Brush HeaderBackgroundColor
		{
			get { return _HeaderBackgroundColor;}
			set { 
					_HeaderBackgroundColor = value;
					brReportHeaderBackgroundColor = _HeaderBackgroundColor; 
				}
		}

		/// <summary>
		/// Gets or Sets the title font
		/// </summary>
		private Font _TitleFont   = new Font("Arial", 12,FontStyle.Bold );
		public  Font TitleFont
		{
			get {return _TitleFont;}
			set { 
					_TitleFont = value;
					fntReportTitleFont = _TitleFont; 
				}
		}

		/// <summary>
		/// Gets or Sets the header font
		/// </summary>
		private Font _HeaderFont   = new Font("Arial", 9,FontStyle.Bold);
		public  Font HeaderFont
		{
			get {return _HeaderFont;}
			set {
					_HeaderFont = value;
					fntReportHeaderFont = _HeaderFont; 
				}
		}
    
		/// <summary>
		/// Gets or Sets the body font
		/// </summary>
		private Font _BodyFont = new Font("Arial", 8);
		public  Font BodyFont  
		{
			get {return _BodyFont;}
			set {
					_BodyFont = value;
					fntReportBodyFont = _BodyFont;
				}
		}

		/// <summary>
		/// Shows or Hides the table border.
		/// </summary>
		private bool _HideGrid  = true;
		public  bool HideGrid
		{
			get {return _HideGrid;}
			set {
					_HideGrid = value;
					bReportHideGrid = _HideGrid;
				}
		}

		/// <summary>
		/// Shows or Hides the report title.
		/// </summary>
		private bool _HasTitle = false;
		public  bool HasTitle 
		{
			get {return _HasTitle;}
			set {
					_HasTitle = value;
					bReportHasTitle = _HasTitle;
				}
		}

        private bool _IsDrawTable = true;
        public bool IsDrawTable
        {
            get { return _IsDrawTable; }
            set
            {
                _IsDrawTable = value;
            }
        }

		/// <summary>
		/// Shows or Hides the report title on all pages.
		/// </summary>
		private bool _ReportTitleFirstPageOnly = true;
		public  bool ReportTitleFirstPageOnly
		{
			get { return _ReportTitleFirstPageOnly;}
			set { 
					_ReportTitleFirstPageOnly = value;
					bReportTitleFirstPageOnly = _ReportTitleFirstPageOnly; 
				}
		}

		/// <summary>
		/// Sets or Gets the report title.
		/// </summary>
		private string _ReportTitle = "";
		public  string ReportTitle  
		{
			get {return _ReportTitle;}
			set {
					_ReportTitle = value;
					sReportTitle = _ReportTitle; 
				}
		}
		
		/// <summary>
		/// Sets or Gets the report logo.
		/// </summary>
		private Image _ReportLogo;  
		public  Image ReportLogo
		{
			get {return _ReportLogo;}
			set {
					_ReportLogo = value;
					imReportLogo = _ReportLogo; 
				}
		}

		/// <summary>
		/// Shows or Hides the report logo
		/// </summary>
		private bool _ReportHasLogo = false;
        public bool ReportHasLogo
        {
            get { return _ReportHasLogo; }
            set
            {
                _ReportHasLogo = value;
                bReportHasLogo = _ReportHasLogo;
            }
        }
    
		/// <summary>
		/// Shows or Hides report totals
		/// </summary>
		private bool _ReportShowTotals = false;
		public bool ReportShowTotals
		{
			get {return _ReportShowTotals;}
			set { 
					_ReportShowTotals = value;
					bReportShowTotals = _ReportShowTotals; 
				}
		}

		#endregion

		#region Methods
		/// <summary>
		/// Initialize fields used in the code
		/// </summary>
		private void InitializeFields()
		{
			bIsLandscape = IsLandscape;
			bReportHasLogo = ReportHasLogo ;
			bReportHasTitle = HasTitle;
			bReportTitleFirstPageOnly = ReportTitleFirstPageOnly;
			iReportLogoHeight = LogoHeight ;
			iReportLogoWidth = LogoWidth ;
			iReportTitleHeight = TitleHeight ;
			fntReportTitleFont = TitleFont ;
			fntReportHeaderFont = HeaderFont ;
			fntReportBodyFont = BodyFont; 
			brReportTitleFontColor = TitleFontColor  ;
			brReportHeaderBackgroundColor = HeaderBackgroundColor ; 
			brReportHeaderFontColor = HeaderFontColor ; 
			bReportHideGrid = HideGrid;
			saReportHeaderCellAlignment = HeaderCellAlignment ;
			saReportTitleAlignment = TitleAlignment ; 
			saReportNumericAlignment = NumericAlignment;
			bReportShowTotals = ReportShowTotals ;
			iTableWidth = TableWidth;
			sReportTitle = ReportTitle; 
			imReportLogo = ReportLogo; 
			iHeaderRowHeight = HeaderRowHeight; 
			iRowHeight = RowHeight;
            pagesPrinted = 0;
            _ReportPrintDocument.DefaultPageSettings.Margins = new Margins(87, 87, 87, 87);
		}

        /// <summary>
        /// A ReDim method similar to the one in VB.
        /// following method is only for arrays of type int.
        /// </summary>
        /// <param name="arr">Array of int</param>
        /// <param name="length">Resize value</param>
		private void ReDim(ref decimal[] arr, int length)
		{
			decimal[] arrTemp=new decimal[length];
			if(length>arr.Length)
			{
				Array.Copy(arr, 0, arrTemp, 0, arr.Length);
				arr = arrTemp;
			}
			else
			{
				Array.Copy(arr, 0, arrTemp, 0, length);
				arr = arrTemp;
			}
		}

		/// <summary>
		/// A IsNumeric function similar to the one in VB.
		/// </summary>
		/// <param name="s">string value to check</param>
		/// <returns>true or false</returns>
		public bool IsNumeric(string s)
		{
			try
			{
				//Decimal.Parse(s);
                Decimal d;
                return   Decimal.TryParse(s, out d);
			}
			catch
			{
				return false;
			}
			return true;
		}	

		/// <summary>
		/// gets the minimum requied height for the row by looping through each column and getting the max height for the cell based on the data size.
		/// </summary>
		/// <param name="dr">data row</param>
		/// <param name="fntReportBodyFont">font for the report body</param>
		/// <param name="colWidth">width for each column</param>
		/// <param name="e">PrintPageEventArgs</param>
		/// <returns></returns>
		private float GetRowHeight(object[] sArray,Font fntReportBodyFont,int colWidth,int defaultValue,  PrintPageEventArgs e)
		{
			int i = 0;
			float compHt = 0;
			float cellHt = 0;

			try
			{
				while (i <= sArray.GetUpperBound(0))
				{
					cellHt = e.Graphics.MeasureString(sArray[i].ToString(),fntReportBodyFont,colWidth).Height;
					compHt = Math.Max(compHt,cellHt);
					i++;
				}
			}
			catch
			{
				//if there is an error revert to default value.
                compHt = defaultValue; 
			}
            
			return compHt + 2 ;
		}

        public void PrintReport(object sender,PrintPageEventArgs e)
		{
		    int tabCol;
		    int tabRows;
		    int tabArrayMax;

			try
			{
				//Store the number of cells in a row for the report table.
				tabCol = dt.Columns.Count;
				//Store the number of rows for the report table.
				tabRows = dt.Rows.Count;
				//Store the number of cells in the table which would be the number of rectangles to render as table cells.
				//Since the product of TabCol and TabRows represents the number of cells in the table body, we need to add 
				//TabCol to the result to include the header row cells.
				tabArrayMax = (tabCol * tabRows) + tabCol;

				if (pagesPrinted == 0)
				{
					ReDim(ref TotCol,tabCol);
				}

                //计算每页打印数
                //int LinesPerPage = (int)(e.MarginBounds.Height / iHeaderRowHeight);
                //int LineNo = this.pagesPrinted * LinesPerPage;
                //if (pagesPrinted != 0)
                //{
                //    ReportRowCount = this.pagesPrinted * LinesPerPage;
                //}

				//Check if the table width specified for the report is greater than the inner page width (excluding margins)
				if (iTableWidth == 0 || iTableWidth > e.MarginBounds.Width)
				{
					iTableWidth = e.MarginBounds.Width;
				}

				//Find out the avg width of each cell by dividing the total table width by the number of columns.
				Pen  vbPen = new Pen(Color.Black);
				//Declare an Array of RectangleF to render the table grid using the DrawReclangles method.
				RectangleF[] rectCell = new RectangleF[tabArrayMax + tabCol];
				//Declare a RectangleF to store the report title.
                //RectangleF titleRect = new RectangleF() ; 
				//Declare a RectangleF to store the report logo.
				RectangleF logoRect = new RectangleF();  
				//Store the X coordinate from where to start rendering.
				int startX  = e.MarginBounds.Top;
				//Store the Y coordinate from where to start rendering.
				int startY  = e.MarginBounds.Top - 35;

				StringFormat modSf = new StringFormat();

				int i  = 0;
				int k  = 0;

				//Check if Logo needs to be displayed
				if (bReportHasLogo)
				{
					if (imReportLogo == null)
					{
                        throw new Exception("Report logo image not found.");
					}
					//Check if the Logo height does not exceed the report title height.
					if (iReportLogoHeight > iReportTitleHeight)
					{
						iReportLogoHeight = iReportTitleHeight;
					}
					logoRect = new RectangleF(startX, startY, iReportLogoWidth, iReportLogoHeight);
					//Render the logo.
					e.Graphics.DrawImage(imReportLogo, logoRect);
				}
				else
				{
					iReportLogoWidth = 0;
					iReportLogoHeight = 0;
				}

				//Check if report title needs to be displayed. 
				if (bReportHasTitle && (pagesPrinted == 0 || !bReportTitleFirstPageOnly))
				{
					modSf.LineAlignment = saReportTitleAlignment;
                    modSf.Alignment = StringAlignment.Center;   // saReportTitleAlignment;
					//titleRect = new RectangleF(startX + iReportLogoWidth , startY, e.MarginBounds.Width - LogoWidth, TitleHeight);
					//Render the title
                    e.Graphics.DrawString(sReportTitle, fntReportTitleFont, brReportTitleFontColor, Convert.ToInt32(Math.Round(Convert.ToDouble(e.PageBounds.Width / 2)))-sReportTitle.Length*11,startY);
				}
				else
				{
					iReportTitleHeight = 0;
				}

                modSf.Trimming = StringTrimming.Word;
                modSf.LineAlignment = StringAlignment.Center;
                modSf.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit;
                modSf.Alignment = StringAlignment.Center;   // saReportHeaderCellAlignment;
                
                int nColIndex = 0;
                //Set the Y coordinates for the next line.
                startY += Math.Max(iReportLogoHeight, iReportTitleHeight) + 10;

                //打印统计项信息
                //Write the total row
                if ((AggrTexts.Count > 1) && (pagesPrinted == 0))
                {
                    List<int> AggrColWidths = new List<int>();  //需要计算

                    startX = e.MarginBounds.Top;
                    
                    //打印"统计量"
                    RectangleF RectF1 = new RectangleF(e.MarginBounds.Top, startY, e.MarginBounds.Width, iRowHeight);
                    e.Graphics.DrawString("统计量:", fntReportHeaderFont, Brushes.Black, RectF1);
                    startY += iRowHeight;
                    startY += 4;

                    //Render the report table header.
                    //Loop through each column of the table and render the column title.
                    int TempY = startY;
                    int MaxCellWidth = 0;
                    for (int k1 = 0; k1 < AggrTexts.Count / 2; k1++)
                    {
                        if (MaxCellWidth < AggrTexts[k1 * 2].Length * 10 + 16)
                            MaxCellWidth = AggrTexts[k1 * 2].Length * 10 + 16;
                    }

                    for (int k1 = 0; k1 < AggrTexts.Count / 2; k1++)
                    {
                        //rectCell[k] = new RectangleF(startX, startY, colWidth, hdrHeight);
                        AggrColWidths.Add(AggrTexts[k1 * 2].Length * 10 + 16);
                        Rectangle r1 = new Rectangle(startX, startY, MaxCellWidth, iRowHeight);
                        //Renders the report table grid
                        e.Graphics.FillRectangle(brReportHeaderBackgroundColor, r1);
                        if (!bReportHideGrid)
                        {
                            e.Graphics.DrawRectangle(vbPen, r1);
                        }
                        e.Graphics.DrawString(AggrTexts[k1 * 2], fntReportBodyFont, brReportHeaderFontColor, r1, modSf);
                        //Set X coordinates for the next cell
                        startY += iRowHeight;
                        nColIndex++;
                        k++;
                    }

                    startX = e.MarginBounds.Top + MaxCellWidth;
                    startY = TempY;

                    MaxCellWidth = 0;
                    for (int k1 = 0; k1 < AggrTexts.Count / 2; k1++)
                    {
                        if (MaxCellWidth < AggrTexts[k1 * 2 + 1].Length * 10 + 16)
                            MaxCellWidth = AggrTexts[k1 * 2 + 1].Length * 10 + 16;
                    }
                    for (int k1 = 0; k1 < AggrTexts.Count / 2; k1++)
                    {
                        Rectangle r1 = new Rectangle(startX, startY, MaxCellWidth, iRowHeight);
                        //Renders the report table grid
                        if (!HideGrid)
                        {
                            e.Graphics.DrawRectangle(vbPen, startX, startY, MaxCellWidth, iRowHeight);
                        }
                        e.Graphics.DrawString(AggrTexts[k1 * 2 + 1].ToString(), fntReportBodyFont, Brushes.Black, r1, modSf);

                        //Set the X coordinate for the next cell.
                        startY += iRowHeight;
                    }
                }

                startX = e.MarginBounds.Top;
                startY += 8;
                nColIndex = 0;
                if (IsDrawTable == true)
                {
                    //create an array of header row values
                    object[] hString = new object[tabCol];
                    dt.Columns.CopyTo(hString, 0);

                    //Render the report table header.
                    //Loop through each column of the table and render the column title.
                    foreach (DataColumn dc in dt.Columns)
                    {
                        //rectCell[k] = new RectangleF(startX, startY, colWidth, hdrHeight);
                        Rectangle r1 = new Rectangle(startX, startY, _ColWidths[nColIndex], iHeaderRowHeight);
                        //Renders the report table grid
                        e.Graphics.FillRectangle(brReportHeaderBackgroundColor, r1);
                        if (!bReportHideGrid)
                        {
                            e.Graphics.DrawRectangle(vbPen, r1);
                        }
                        e.Graphics.DrawString(dc.ToString(), fntReportHeaderFont, brReportHeaderFontColor, r1, modSf);
                        //Set X coordinates for the next cell
                        startX += _ColWidths[nColIndex];
                        nColIndex++;
                        k++;
                    }
                    //Set the X coordinate for the next row.
                    startX = e.MarginBounds.Top;
                    //Set the Y coordinates for the next row.
                    startY += iHeaderRowHeight;
                }

				//Store current coordinate on the page.
                int yPos = startY;

                /*
                //print per line
                int count = 0;
                while ((count < lines) && (LineNo < dt.Rows.Count))
                {
                    yPos = e.MarginBounds.Top + count * iRowHeight;

                    LineNo++;
                    count++;
                }

                if (dt.Rows.Count > LineNo)
                {
                    e.HasMorePages = true;
                }
                else
                {
                    e.HasMorePages = false;
                }*/

				//Render report table body till the bottom margin of the page
				while (yPos <= e.MarginBounds.Bottom)
				{
					int j  = 0;
                    nColIndex = 0;
					DataRow dr ;

					if ((IsDrawTable == true) && (ReportRowCount < dt.Rows.Count))
                    {
                        dr = dt.Rows[ReportRowCount];

                        //gets the maximum height required for the row.
                        //iRowHeight = Convert.ToInt32(GetRowHeight(dr.ItemArray, fntReportBodyFont, _ColWidths[nColIndex], iRowHeight, e));

                        nColIndex = 0;
                        k = 0;
                        //Loop through each row and column to render the cells.
                        foreach (DataColumn dc in dt.Columns)
                        {
                            rectCell[k] = new RectangleF(startX, startY, _ColWidths[nColIndex], iRowHeight);
                            //Renders the report table grid
                            if (!bReportHideGrid)
                            {
                                e.Graphics.DrawRectangle(vbPen, startX, startY, _ColWidths[nColIndex], iRowHeight);
                            }
                            //Right align numeric values
                            if (IsNumeric(dr.ItemArray[j].ToString()))
                            {
                                //Get totals for all numeric columns
                                TotCol[j] = TotCol[j] + Convert.ToDecimal(dr.ItemArray[j]);
                            }
                            else
                            {
                                TotCol[j] = -1;
                            }

                            e.Graphics.DrawString(dr.ItemArray[j].ToString(), fntReportBodyFont, Brushes.Black, rectCell[k], modSf);

                            //Set the X coordinate for the next cell.
                            startX += _ColWidths[nColIndex];
                            nColIndex++;
                            j++;
                            k++;
                        }

                        //Set the X coordinate for the next row.
                        startX = e.MarginBounds.Top;
                        //Set the Y coordinate for the next row.
                        startY += iRowHeight;
                        //Set the last rendered coordinate.
                        yPos = startY;
                        i++;
                        ReportRowCount++;
                        e.HasMorePages = true;
                    }

                    //Check if current rendered row count = the total number of rows and set the HasMorePages property to false.
                    if ((ReportRowCount == dt.Rows.Count) || (IsDrawTable == false))
                    {
                        startY += 8;
                        //打印时间
                        RectangleF RectF2 = new RectangleF(e.MarginBounds.Top, startY, e.MarginBounds.Width, iRowHeight);
                        e.Graphics.DrawString(DateTime.Now.ToShortDateString(), fntReportBodyFont, Brushes.Black, RectF2);
                        startY += iRowHeight;

                        //Set the last rendered coordinate.
                        yPos = startY;
                        i++;
                        ReportRowCount = 0;
                        e.HasMorePages = false;
                        
                        break;
                    }
                    else if (ReportRowCount >= dt.Rows.Count)
                    {
                        e.HasMorePages = false;
                        ReportRowCount = 0;
                        break;
                    }
				}
				pagesPrinted ++;

                //Renders the page count
				e.Graphics.DrawString("第" +pagesPrinted.ToString() + "页", fntReportHeaderFont, brReportHeaderFontColor, Convert.ToInt32 (Math.Round (Convert.ToDouble (e.PageBounds.Width / 2))), e.MarginBounds.Bottom + 30);
				//Reset properties after final page
				if (!e.HasMorePages)
				{
                    pagesPrinted = 0;
					TitleHeight = 40;
				}
			}
			catch(Exception ex)
			{
				//throw the error to the calling procedure.
				
			}
			finally
			{
				e.Graphics.Dispose();
			}
		}
		#endregion
	
	}
}
